package goalie.common;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import goalie.Component;

/**
 * This Component executes a command from the command line. The command can
 * be specified using input/let argument values by using a placeholder 
 * ${var}.
 * An argument 'file' specifies which other arguments are to be treated as
 * files and deleted afterwards. White spaces in file arguments are removed in 
 * order to make their composition easier.
 * 
 * @author beroth
 *
 */
public class CommandLine implements Component {
  
  public static String REFERRED_NAME = "commandline";

  // The command to run. Parameters can be given as variables, in the form
  // ${parameter}.
  public static String COMMAND =  "command";
  // Names of parameters with generated files that have to be deleted 
  // afterwards. Whitespace in parameters that are files are removed.
  public static String FILES = "files";
  
  @Override
  public void cleanup(Map<String, String> outputs) throws IOException {
    for (String fileName : outputs.values()) {
      File f = new File(fileName);
      f.delete();
    }
  }

  @Override
  public Map<String, String> run(Map<String, String> params) throws IOException {
    Map<String, String> files = new HashMap<String, String>();
    if (params.containsKey(FILES)) {
      for (String fileParam : params.get(FILES).split("\\s")) {
        files.put(fileParam, params.get(fileParam).replaceAll("\\s", ""));
      }
    }
    
    String command = params.get(COMMAND);
    for (String param : params.keySet()) {
      if (files.containsKey(param)) {
        command = replace(command, param, files.get(param));
      } else {
        command = replace(command, param, params.get(param));
      }
    }
    
    Process p = Runtime.getRuntime().exec(command);
    try {
      p.waitFor();
    } catch (InterruptedException e) {
      e.printStackTrace();
      throw new IOException("Could not execute command.");
    }
    
    return files;
  }
  
  private String replace(String command, String param, String value) {
    String paramVariable = "${" + param + "}";
    return command.replaceAll(Pattern.quote(paramVariable), value);
  }

}
